package mcore

import (
	"bytes"
	"github.com/howcrazy/xconv"
	"net/url"
	"sort"
	"strings"
	"unsafe"
)

var Strings = mstrings{}

type mstrings struct {
}

func (domain mstrings) Str2bytes(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s))
	h := [3]uintptr{x[0], x[1], x[1]}
	return *(*[]byte)(unsafe.Pointer(&h))
}

func (domain mstrings) Bytes2str(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}
func (domain mstrings) FormUrl(url string, data map[string]string) string {
	buffer := bytes.Buffer{}
	buffer.WriteString(url)
	buffer.WriteString("?")
	buffer.WriteString(Strings.EncodeFormStr(data))
	return buffer.String()
}
func (domain mstrings) EncodeFormStr(data map[string]string) string {
	if data == nil {
		return ""
	}
	var buf strings.Builder
	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := data[k]
		keyEscaped := url.QueryEscape(k)

		if buf.Len() > 0 {
			buf.WriteByte('&')
		}
		buf.WriteString(keyEscaped)
		buf.WriteByte('=')
		buf.WriteString(url.QueryEscape(v))

	}
	return buf.String()
}
func (domain mstrings) EncodeForm(data map[string]any) string {
	if data == nil {
		return ""
	}
	var buf strings.Builder
	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := data[k]
		keyEscaped := url.QueryEscape(k)

		if buf.Len() > 0 {
			buf.WriteByte('&')
		}
		buf.WriteString(keyEscaped)
		buf.WriteByte('=')
		var value string
		xconv.Convert(v, &value)
		buf.WriteString(url.QueryEscape(value))

	}
	return buf.String()
}

func (domain mstrings) ToInt64(val any) (res int64) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToInt(val any) (res int) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToInt8(val any) (res int8) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToInt16(val any) (res int16) {
	xconv.Convert(val, &res)
	return res
}
func (domain mstrings) ToInt32(val any) (res int32) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToFloat32(val any) (res float32) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToFloat64(val any) (res float64) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToBool(val any) (res bool) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToStr(val any) (res string) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToUint(val any) (res uint) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToUint8(val any) (res uint8) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToUint16(val any) (res uint16) {
	xconv.Convert(val, &res)
	return res
}

func (domain mstrings) ToUint32(val any) (res uint32) {
	xconv.Convert(val, &res)
	return res
}
